
#include "Partition.h"
#include <iostream>

Partition::Iterator Partition::Iterator::operator++(void) {
        if(partition->currPart[0]!=1) {
        // if the first element of the <strong class="highlight">partition</strong> is 1
        // then the <strong class="highlight">partition</strong> is { 1, ... , 1 } and we're done
                int k = 0;
                for(unsigned int i=1; i < partition->currPart.size(); i++) {
                        // finds the rightmost element != 1
                        if(partition->currPart[i]>1) {
                                k++;
                        }
                }
                partition->currPart[k]--; // decreases the rightmost element != 1
                partition->currPart.insert(partition->currPart.begin()+k+1, 1);
                // inserts 1 at its right
                bool loop_again = true;
                while(loop_again) {
                        int grouped = 0;
                        for(unsigned int i=k+1; i < partition->currPart.size(); i++) {
                                // groups trailing 1s preserving
                                // monotonicity of the sequence
                                if(grouped+partition->currPart[i]
                                        <= partition->currPart[k]) {
                                        grouped += partition->currPart[i];
                                        partition->currPart.erase(partition->currPart.begin()+i);
                                        // deletes 1s as they're added
                                        i--;
                                }
                        }
                        if(grouped!=0) { // inserts the grouped 1s (if any)
                                partition->currPart.insert(partition->currPart.begin()+k+1, grouped);
                        }
                        int sum = 0;
                        for(unsigned int j = 0; j  < partition->currPart.size(); j++) {
                                if(partition->currPart[j]==1) {
                                        sum++;
                                        // calculates the amount of remaining 1s
                                }
                        }
                        if(sum>1&&grouped!=0) {
                                // if there are more trailing 1s and we have just
                                // grouped a few it sets the flag for another loop
                                k++;
                                loop_again = true;
                        }
                        else {
                                loop_again = false;
                                // this <strong class="highlight">partition</strong> is done,
                                // so we exit the inner while loop
                        }
                }
        }
        else {
                *this = Iterator(partition->end());
        }
        return *this;
}

void printPartition(std::vector<int>& part) {
        for(unsigned int i = 0; i < part.size() - 1; i++) {
                std::cout << part[i] << " + ";
        }
        std::cout << part[part.size()-1] << std::endl;
}
